﻿/* 
	======================================================================== 
		File name：		UnityControllerFactory
		Module:			Unity Helper - Controller Factory	
		Author：			David Gu(Master HaKu)
		Create Time：	2013/8/31 11:11:21
		Modify By:		
		Modify Date:	
	======================================================================== 
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Reflection;
using Microsoft.Practices.Unity;
using System.Globalization;

namespace Zeus.IOC.Unity
{
    public class UnityControllerFactory : DefaultControllerFactory
    {
        /// <summary>
        /// 创建一个 Controller 类实例，覆盖基类方法
        /// summary>
        /// <param name="aRequestContext">Http请求上下文对象param>
        /// <param name="aControllerType">Controller类型param>
        /// <returns>
        /// 返回 IController 类实例。
        /// returns>
        /// <remarks>
        /// 2010-10-09 [Max] 创建。
        /// remarks>
        protected override IController GetControllerInstance(RequestContext aRequestContext, Type aControllerType)
        {
            //不适用的方式：
            //if ( aControllerType == null )
            //{
            //    throw new ArgumentNullException( "aControllerType" );
            //}

            //if ( !typeof( IController ).IsAssignableFrom( aControllerType ) )
            //{
            //    throw new ArgumentException( string.Format( "{0} 不是 Controller。", aControllerType.Name ), "aControllerType" );
            //}
            //适用的方式：
            if (aControllerType == null)
            {
                throw new HttpException(404, String.Format(CultureInfo.CurrentUICulture, "未发现指定的 Controller {0}。", aRequestContext.HttpContext.Request.Path));
            }
            if (!typeof(IController).IsAssignableFrom(aControllerType))
            {
                throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, "{0} 不是 Controller。", aControllerType), "aControllerType");
            }
            try
            {
                IUnityContainer container = GetContainer(aRequestContext);
                return (IController)container.Resolve(aControllerType);
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, "无法创建 Controller {0}。", aControllerType), ex);
            }
        }

        /// <summary>
        /// 获取依赖注入容器对象
        /// summary>
        /// <param name="aContext">Http请求上下文对象param>
        /// <returns>
        /// 返回 IUnityContainer 类实例。
        /// returns>
        /// <remarks>
        /// 2010-09-18 [Max] 创建。
        /// remarks>
        protected virtual IUnityContainer GetContainer(RequestContext aContext)
        {
            if (aContext == null)
            {
                throw new ArgumentNullException("aContext");
            }

            var unityApp = aContext.HttpContext.ApplicationInstance as IUnityMvcApplication;
            if (unityApp == null)
            {
                throw new InvalidOperationException("MvcHttpApplication 对象必须从 UnityMvcApplication 继承。");
            }

            IUnityContainer container = unityApp.Container;
            if (container == null)
            {
                throw new InvalidOperationException("依赖注入容器对象无法访问，请查看您的 MvcHttpApplication 类定义是否正确。");
            }
            return container;
        }
    }
}
